package com.education.ai.service.impl;

import com.education.ai.entity.Exercise;
import com.education.ai.model.ExerciseRequest;
import com.education.ai.repository.ExerciseRepository;
import com.education.ai.service.ExerciseService;
import com.education.ai.service.AiService;
import com.education.ai.util.TeacherContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 练习题服务实现类
 */
@Service
@Slf4j
public class ExerciseServiceImpl implements ExerciseService {

    @Autowired
    private ExerciseRepository exerciseRepository;
    
    @Autowired
    @Qualifier("qwenWebClient")
    private WebClient qwenWebClient;
    
    @Autowired
    private ObjectMapper objectMapper;
    
    @Autowired
    private AiService aiService;
    
    @Value("${qwen.model:qwen-max}")
    private String model;

    @Override
    public List<Exercise> getAllExercises() {
        return exerciseRepository.findAll();
    }

    @Override
    public Exercise getExerciseById(Long id) {
        return exerciseRepository.findById(id).orElse(null);
    }

    @Override
    public List<Exercise> getExercisesBySubject(String subject) {
        return exerciseRepository.findBySubject(subject);
    }

    @Override
    public List<Exercise> getExercisesByGrade(String grade) {
        return exerciseRepository.findByGrade(grade);
    }

    @Override
    public List<Exercise> getExercisesBySubjectAndGrade(String subject, String grade) {
        return exerciseRepository.findBySubjectAndGrade(subject, grade);
    }

    @Override
    public List<Exercise> getExercisesBySubjectAndGradeAndTopic(String subject, String grade, String topic) {
        return exerciseRepository.findBySubjectAndGradeAndTopic(subject, grade, topic);
    }

    @Override
    public Exercise saveExercise(Exercise exercise) {
        return exerciseRepository.save(exercise);
    }

    @Override
    public void deleteExercise(Long id) {
        exerciseRepository.deleteById(id);
    }

    @Override
    public List<Exercise> generateExercises(String subject, String grade, String topic, int count) {
        return generateExercises(subject, grade, topic, count, null);
    }

    @Override
    public List<Exercise> generateExercises(String subject, String grade, String topic, int count, String teacherId) {
        ExerciseRequest request = new ExerciseRequest();
        request.setSubject(subject);
        request.setGrade(grade);
        request.setTopic(topic);
        request.setCount(count);
        request.setTeacherId(teacherId);
        return generateExercises(request);
    }

    @Override
    public List<Exercise> generateExercises(ExerciseRequest request) {
        // 构建提示词
        String prompt = buildPrompt(request);
        
        // 调用AI服务生成题目
        String response = aiService.generateContent(prompt);
        
        // 解析AI响应
        List<Exercise> exercises = parseAIResponse(response);
        
        // 设置教师ID
        exercises.forEach(exercise -> {
            exercise.setTeacherId(request.getTeacherId());
            exercise.setSubject(request.getSubject());
            exercise.setGrade(request.getGrade());
            exercise.setTopic(request.getTopic());
            exercise.setQuestionType(request.getQuestionType());
            exercise.setDifficulty(request.getDifficulty());
        });
        
        // 保存到数据库
        return exerciseRepository.saveAll(exercises);
    }

    private String buildPrompt(ExerciseRequest request) {
        return String.format(
            "请生成以下要求的练习题：\n" +
            "学科：%s\n" +
            "年级：%s\n" +
            "主题：%s\n" +
            "题目类型：%s\n" +
            "难度：%s\n" +
            "题目数量：%d\n" +
            "请按照以下格式返回：\n" +
            "题目1：\n" +
            "内容：\n" +
            "答案：\n" +
            "解析：\n" +
            "难度：\n" +
            "---\n",
            request.getSubject(),
            request.getGrade(),
            request.getTopic(),
            request.getQuestionType(),
            request.getDifficulty(),
            request.getCount()
        );
    }

    private List<Exercise> parseAIResponse(String response) {
        List<Exercise> exercises = new ArrayList<>();
        String[] exerciseBlocks = response.split("---");
        
        for (String block : exerciseBlocks) {
            if (block.trim().isEmpty()) continue;
            
            Exercise exercise = Exercise.builder()
                .content(extractField(block, "内容："))
                .answer(extractField(block, "答案："))
                .analysis(extractField(block, "解析："))
                .difficulty(extractField(block, "难度："))
                .createdTime(LocalDateTime.now())
                .build();
            
            exercises.add(exercise);
        }
        
        return exercises;
    }

    private String extractField(String block, String fieldName) {
        int startIndex = block.indexOf(fieldName);
        if (startIndex == -1) return "";
        
        startIndex += fieldName.length();
        int endIndex = block.indexOf("\n", startIndex);
        if (endIndex == -1) endIndex = block.length();
        
        return block.substring(startIndex, endIndex).trim();
    }

    @Override
    public List<Map<String, Object>> formatExercisesForFrontend(List<Exercise> exercises, List<String> questionTypes) {
        List<Map<String, Object>> formattedExercises = new ArrayList<>();
        
        // 筛选出前端需要的题型的习题
        List<Exercise> filteredExercises = exercises.stream()
            .filter(e -> {
                String type = convertQuestionType(e.getQuestionType());
                return questionTypes.contains(type);
            })
            .collect(Collectors.toList());
        
        for (Exercise exercise : filteredExercises) {
            Map<String, Object> formattedExercise = new HashMap<>();
            formattedExercise.put("type", convertQuestionType(exercise.getQuestionType()));
            formattedExercise.put("content", exercise.getContent());
            formattedExercise.put("answer", exercise.getAnswer());
            formattedExercise.put("explanation", exercise.getAnalysis());
            
            // 如果是选择题，解析选项
            if (exercise.getQuestionType().contains("选择题")) {
                Map<String, String> options = parseOptions(exercise.getContent());
                formattedExercise.put("options", options);
            }
            
            formattedExercises.add(formattedExercise);
        }
        
        return formattedExercises;
    }
    
    @Override
    public List<Exercise> saveExercisesFromFrontend(String subject, String stage, String chapter, String textbook, List<Map<String, Object>> questions) {
        // 调用带teacherId参数的方法，传入null或从上下文获取
        return saveExercisesFromFrontend(subject, stage, chapter, textbook, questions, TeacherContext.getTeacherId());
    }
    
    @Override
    public List<Exercise> saveExercisesFromFrontend(String subject, String stage, String chapter, String textbook, List<Map<String, Object>> questions, String teacherId) {
        List<Exercise> savedExercises = new ArrayList<>();
        
        for (Map<String, Object> question : questions) {
            String type = (String) question.get("type");
            String content = (String) question.get("content");
            String answer = (String) question.get("answer");
            String explanation = (String) question.get("explanation");
            
            Exercise exercise = Exercise.builder()
                .subject(subject)
                .grade(stage)
                .topic(chapter)
                .questionType(convertFrontendType(type))
                .content(content)
                .answer(answer)
                .analysis(explanation)
                .difficulty("中等") // 默认设置为中等难度
                .teacherId(teacherId) // 设置教师ID
                .createdTime(LocalDateTime.now())
                .build();
                
            // 如果是选择题，处理选项
            if (type.equals("multiple-choice")) {
                @SuppressWarnings("unchecked")
                Map<String, String> options = (Map<String, String>) question.get("options");
                if (options != null) {
                    // 将选项添加到题目内容中
                    StringBuilder contentWithOptions = new StringBuilder(content);
                    contentWithOptions.append("\n");
                    for (Map.Entry<String, String> option : options.entrySet()) {
                        contentWithOptions.append(option.getKey())
                            .append(". ")
                            .append(option.getValue())
                            .append("\n");
                    }
                    exercise.setContent(contentWithOptions.toString());
                }
            }
            
            Exercise savedExercise = exerciseRepository.save(exercise);
            savedExercises.add(savedExercise);
        }
        
        return savedExercises;
    }
    
    @Override
    public List<Map<String, Object>> getHotExercises(Integer page, Integer pageSize, String stage, String subject, String startDate, String endDate) {
        // 模拟热点考题数据，实际项目中应该从数据库查询
        List<Map<String, Object>> hotExercises = new ArrayList<>();
        
        // 分页偏移
        int offset = (page - 1) * pageSize;
        
        // 生成模拟数据
        for (int i = 0; i < pageSize; i++) {
            int index = offset + i;
            if (index < 100) { // 假设总共有100道热点题
                Map<String, Object> exercise = new HashMap<>();
                exercise.put("type", i % 3 == 0 ? "multiple-choice" : (i % 3 == 1 ? "fill-blank" : "short-answer"));
                exercise.put("content", "热点考题" + (index + 1) + "：" + getExampleQuestion(subject, stage, index));
                
                if (i % 3 == 0) { // 选择题
                    Map<String, String> options = new HashMap<>();
                    options.put("A", "选项A");
                    options.put("B", "选项B");
                    options.put("C", "选项C");
                    options.put("D", "选项D");
                    exercise.put("options", options);
                }
                
                exercise.put("answer", "参考答案" + (index + 1));
                exercise.put("explanation", "解析" + (index + 1));
                exercise.put("hotness", 100 - index);
                exercise.put("usageCount", 500 - index * 5);
                exercise.put("correctRate", 0.5 + (index % 50) * 0.01);
                
                hotExercises.add(exercise);
            }
        }
        
        return hotExercises;
    }
    
    @Override
    public int countHotExercises(String stage, String subject, String startDate, String endDate) {
        // 模拟数据，实际应该从数据库统计
        return 100;
    }
    
    @Override
    public List<Map<String, Object>> getMistakes(Integer page, Integer pageSize, String stage, String subject, String mistakeType) {
        // 模拟高频错题数据
        List<Map<String, Object>> mistakes = new ArrayList<>();
        
        // 分页偏移
        int offset = (page - 1) * pageSize;
        
        // 生成模拟数据
        for (int i = 0; i < pageSize; i++) {
            int index = offset + i;
            if (index < 100) { // 假设总共有100道高频错题
                Map<String, Object> mistake = new HashMap<>();
                mistake.put("type", mistakeType != null ? mistakeType : (i % 4 == 0 ? "concept" : (i % 4 == 1 ? "calculation" : (i % 4 == 2 ? "thinking" : "knowledge"))));
                mistake.put("content", "高频错题" + (index + 1) + "：" + getExampleQuestion(subject, stage, index));
                
                if (i % 3 == 0) { // 选择题
                    Map<String, String> options = new HashMap<>();
                    options.put("A", "选项A");
                    options.put("B", "选项B");
                    options.put("C", "选项C");
                    options.put("D", "选项D");
                    mistake.put("options", options);
                }
                
                mistake.put("correctAnswer", "正确答案" + (index + 1));
                mistake.put("errorReason", "错误原因" + (index + 1));
                mistake.put("solution", "解题思路" + (index + 1));
                mistake.put("errorCount", 200 - index * 2);
                mistake.put("errorRate", 0.7 - (index % 50) * 0.01);
                mistake.put("masteryLevel", index % 5);
                
                mistakes.add(mistake);
            }
        }
        
        return mistakes;
    }
    
    @Override
    public int countMistakes(String stage, String subject, String mistakeType) {
        // 模拟数据，实际应该从数据库统计
        return 100;
    }
    
    @Override
    public Map<String, Object> getMistakesStats(String stage, String subject) {
        // 模拟错题统计信息
        Map<String, Object> stats = new HashMap<>();
        stats.put("totalMistakes", 100);
        stats.put("averageErrorRate", 0.65);
        stats.put("mostCommonType", "concept");
        stats.put("masteredQuestions", 35);
        
        return stats;
    }
    
    @Override
    public List<Map<String, String>> getTextbookChapters(String subject, String textbook) {
        // 模拟教材章节数据
        List<Map<String, String>> chapters = new ArrayList<>();
        
        // 根据学科和教材动态生成章节
        int chapterCount = "renjiao".equals(textbook) ? 10 : 8;
        
        for (int i = 1; i <= chapterCount; i++) {
            Map<String, String> chapter = new HashMap<>();
            chapter.put("value", "chapter_" + i);
            chapter.put("label", "第" + i + "章: " + getChapterTitle(subject, i));
            chapters.add(chapter);
        }
        
        return chapters;
    }
    
    @Override
    public List<Map<String, Object>> getExerciseHistory(String teacherId, int page, int size) {
        log.info("获取历史记录 - 教师ID: {}, 页码: {}, 每页大小: {}", teacherId, page, size);
        
        // 创建分页请求，页码从0开始
        PageRequest pageRequest = PageRequest.of(page - 1, size, Sort.by(Sort.Direction.DESC, "createdTime"));
        log.info("创建分页请求 - 页码: {}, 每页大小: {}, 排序: createdTime DESC", pageRequest.getPageNumber(), pageRequest.getPageSize());
        
        // 查询分页数据
        Page<Exercise> exercises = exerciseRepository.findByTeacherId(teacherId, pageRequest);
        log.info("查询结果 - 总元素数: {}, 总页数: {}, 当前页元素数: {}", 
                 exercises.getTotalElements(), exercises.getTotalPages(), exercises.getNumberOfElements());
        
        // 转换为Map列表
        List<Map<String, Object>> result = exercises.getContent().stream()
                .map(exercise -> {
                    Map<String, Object> map = new HashMap<>();
                    map.put("id", exercise.getId());
                    map.put("subject", exercise.getSubject());
                    map.put("grade", exercise.getGrade());
                    map.put("topic", exercise.getTopic());
                    map.put("questionType", exercise.getQuestionType());
                    map.put("content", exercise.getContent());
                    map.put("answer", exercise.getAnswer());
                    map.put("analysis", exercise.getAnalysis());
                    map.put("difficulty", exercise.getDifficulty());
                    map.put("createdTime", exercise.getCreatedTime());
                    return map;
                })
                .collect(Collectors.toList());
        
        log.info("转换后的结果大小: {}", result.size());
        
        // 添加总记录数信息
        if (!result.isEmpty()) {
            result.get(0).put("total", exercises.getTotalElements());
            log.info("在结果中添加总记录数: {}", exercises.getTotalElements());
        } else {
            // 如果没有记录，创建一个只包含total的map
            Map<String, Object> totalMap = new HashMap<>();
            totalMap.put("total", exercises.getTotalElements());
            result.add(totalMap);
            log.info("没有记录，创建包含总记录数的Map: {}", exercises.getTotalElements());
        }
        
        return result;
    }
    
    // =================== 辅助方法 ===================
    
    /**
     * 将内部题型转换为前端题型格式
     */
    private String convertQuestionType(String type) {
        if (type == null) return "short-answer";
        
        if (type.contains("选择题")) {
            return "multiple-choice";
        } else if (type.contains("填空题")) {
            return "fill-blank";
        } else if (type.contains("判断题")) {
            return "true-false";
        } else {
            return "short-answer";
        }
    }
    
    /**
     * 将前端题型转换为内部题型格式
     */
    private String convertFrontendType(String type) {
        switch (type) {
            case "multiple-choice":
                return "选择题";
            case "fill-blank":
                return "填空题";
            case "true-false":
                return "判断题";
            case "short-answer":
                return "解答题";
            default:
                return "解答题";
        }
    }
    
    /**
     * 从题目内容中解析选项
     */
    private Map<String, String> parseOptions(String content) {
        Map<String, String> options = new HashMap<>();
        
        // 简单解析，实际情况可能需要更复杂的解析逻辑
        if (content != null && content.contains("\n")) {
            String[] lines = content.split("\n");
            for (String line : lines) {
                line = line.trim();
                if (line.length() > 2 && "ABCD".contains(line.substring(0, 1)) && line.charAt(1) == '.') {
                    String key = line.substring(0, 1);
                    String value = line.substring(2).trim();
                    options.put(key, value);
                } else if (line.length() > 2 && "ABCD".contains(line.substring(0, 1)) && line.charAt(1) == ':') {
                    String key = line.substring(0, 1);
                    String value = line.substring(2).trim();
                    options.put(key, value);
                }
            }
        }
        
        // 如果没有解析到选项，生成示例选项
        if (options.isEmpty()) {
            options.put("A", "选项A");
            options.put("B", "选项B");
            options.put("C", "选项C");
            options.put("D", "选项D");
        }
        
        return options;
    }
    
    /**
     * 获取示例问题内容
     */
    private String getExampleQuestion(String subject, String stage, int index) {
        if (subject == null) subject = "math";
        if (stage == null) stage = "junior";
        
        Map<String, List<String>> questionMap = new HashMap<>();
        
        // 数学题目示例
        questionMap.put("math", Arrays.asList(
            "计算1+1的结果是多少？",
            "解方程x + 5 = 12",
            "已知三角形的三个顶点坐标为A(1,2), B(3,4), C(5,1)，求三角形的面积。",
            "如果f(x) = x^2 - 3x + 2，求f(2)的值。",
            "判断数列{1, 3, 5, 7, 9, ...}是等差数列还是等比数列？"
        ));
        
        // 英语题目示例
        questionMap.put("english", Arrays.asList(
            "用适当的连词填空：_____ it was raining, we went out.",
            "将下列句子改为被动语态：People speak English in many countries.",
            "选择正确的时态：I (have been / has been / had been) to Beijing three times.",
            "翻译句子：我昨天看了一部有趣的电影。",
            "阅读短文并回答问题..."
        ));
        
        // 物理题目示例
        questionMap.put("physics", Arrays.asList(
            "一个物体以10m/s的初速度竖直向上抛出，重力加速度为10m/s²，求物体达到最高点的时间。",
            "如果光速是3.0×10^8 m/s，那么光穿过厚度为0.03m的玻璃需要多少时间？",
            "解释牛顿第一定律。",
            "计算电阻为5Ω的导体在20V电压下的电流大小。",
            "一个物体在水平面上以4m/s的速度运动，如果摩擦系数为0.2，重力加速度为10m/s²，求物体停止运动时运动的距离。"
        ));
        
        List<String> questions = questionMap.getOrDefault(subject, questionMap.get("math"));
        return questions.get(index % questions.size());
    }
    
    /**
     * 获取章节标题
     */
    private String getChapterTitle(String subject, int chapterIndex) {
        if (subject == null) subject = "math";
        
        Map<String, List<String>> titleMap = new HashMap<>();
        
        // 数学章节标题
        titleMap.put("math", Arrays.asList(
            "数与代数",
            "函数",
            "几何",
            "概率与统计",
            "三角函数",
            "向量",
            "微积分初步",
            "线性代数初步",
            "数列",
            "立体几何"
        ));
        
        // 英语章节标题
        titleMap.put("english", Arrays.asList(
            "问候与介绍",
            "日常生活",
            "学校生活",
            "家庭与朋友",
            "交通与旅行",
            "饮食与健康",
            "环境与保护",
            "文化与传统",
            "科技与未来",
            "职业与理想"
        ));
        
        // 物理章节标题
        titleMap.put("physics", Arrays.asList(
            "力学基础",
            "热学",
            "电磁学",
            "光学",
            "原子物理",
            "相对论初步",
            "量子物理初步",
            "能量转换",
            "波动与振动",
            "力学实验"
        ));
        
        List<String> titles = titleMap.getOrDefault(subject, titleMap.get("math"));
        return titles.get((chapterIndex - 1) % titles.size());
    }

    @Override
    public List<Exercise> generateExercises(String stage, String subject, String textbook, String chapter, int count, List<String> questionTypes, String teacherId) {
        // 构建提示词
        String prompt = String.format(
            "请生成以下要求的练习题：\n" +
            "学习阶段：%s\n" +
            "学科：%s\n" +
            "教材：%s\n" +
            "章节：%s\n" +
            "题目数量：%d\n" +
            "题目类型：%s\n" +
            "请按照以下格式返回：\n" +
            "题目1：\n" +
            "内容：\n" +
            "答案：\n" +
            "解析：\n" +
            "难度：\n" +
            "---\n",
            stage, subject, textbook, chapter, count, String.join(",", questionTypes)
        );
        
        // 调用AI服务生成题目
        String response = aiService.generateContent(prompt);
        
        // 解析AI响应
        List<Exercise> exercises = parseAIResponse(response);
        
        // 设置教师ID
        exercises.forEach(exercise -> {
            exercise.setTeacherId(teacherId);
            exercise.setSubject(subject);
            exercise.setGrade(stage);
            exercise.setTopic(chapter);
            exercise.setQuestionType(String.join(",", questionTypes));
        });
        
        // 保存到数据库
        return exerciseRepository.saveAll(exercises);
    }

    @Override
    public List<Exercise> generateExercises(String stage, String subject, String textbook, String chapter, int count, List<String> questionTypes) {
        return generateExercises(stage, subject, textbook, chapter, count, questionTypes, null);
    }
} 